package com.xingda.packing.dmss.minitor.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.xingda.packing.dmss.domain.PackProductionLine;
import com.xingda.packing.dmss.enums.BoxLocationNo;
import com.xingda.packing.dmss.events.dto.AGVSchedulingParam;
import com.xingda.packing.dmss.http.AGVHttp;
import com.xingda.packing.dmss.minitor.dto.AGVTaskDto;
import com.xingda.packing.dmss.minitor.dto.MesToAgv;
import com.xingda.packing.dmss.minitor.entity.PkAgvScheduling;
import com.xingda.packing.dmss.minitor.entity.PkAgvTask;
import com.xingda.packing.dmss.minitor.mapper.PkAgvSchedulingMapper;
import com.xingda.packing.dmss.minitor.mapper.PkAgvTaskMapper;
import com.xingda.packing.dmss.minitor.service.IPkAgvSchedulingService;
import com.xingda.packing.dmss.minitor.service.IPkBoxLocationRealtionService;
import com.xingda.packing.dmss.plc.service.PlcDirectiveService;
import lombok.Getter;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;
import java.util.Date;
import java.util.Objects;

@Slf4j
@Service
public class IPkAgvSchedulingServiceImpl extends ServiceImpl<PkAgvSchedulingMapper, PkAgvScheduling> implements IPkAgvSchedulingService {
    @Resource
    private PkAgvSchedulingMapper pkAgvSchedulingMapper;
    @Value("${com.xingda.region}")
    @Getter
    private String region;
    @Resource
    private PlcDirectiveService plcDirectiveService;
    @Resource
    private PackProductionLine packProductionLine;
    @Resource
    private PkAgvTaskMapper pkAgvTaskMapper;
    @Resource
    private IPkBoxLocationRealtionService iPkBoxLocationRealtionService;


    @Override
    public IPage<PkAgvScheduling> getList(Integer actionType, Integer finishState, Long current, Long size) {
        LambdaQueryWrapper<PkAgvScheduling> pkAgvSchedulingLambdaQueryWrapper = Wrappers.lambdaQuery();
        pkAgvSchedulingLambdaQueryWrapper.eq(actionType != null && actionType != -1, PkAgvScheduling::getActionType, actionType)
                .eq(finishState != null && finishState != -1, PkAgvScheduling::getFinishState, finishState)
                .orderByDesc(PkAgvScheduling::getStartTime);
        current = current == null ? 1 : current;
        size = size == null ? 20 : size;
        IPage<PkAgvScheduling> page = new Page<>(current, size, true);
        return pkAgvSchedulingMapper.selectPage(page, pkAgvSchedulingLambdaQueryWrapper);
    }

    @Override
    public void send(Integer id) {
        PkAgvScheduling pkAgvScheduling = pkAgvSchedulingMapper.selectById(id);
        pkAgvScheduling.setActionType(2);
        pkAgvScheduling.setStartTime(new Date());
        pkAgvSchedulingMapper.updateById(pkAgvScheduling);
        AGVSchedulingParam schedulingParam = new AGVSchedulingParam();
        BeanUtils.copyProperties(pkAgvScheduling, schedulingParam);
        AGVHttp.save(schedulingParam);
    }

    @Override
    public MesToAgv status() {
        MesToAgv mesToAgv = new MesToAgv();
        mesToAgv.setAllowPass(packProductionLine.isAllowPass());
        mesToAgv.setStopSignal(plcDirectiveService.isStopSignal());
        return mesToAgv;
    }

    @Override
    public void insert(AGVTaskDto agvTaskDto) {
        PkAgvScheduling pkAgvScheduling = null;
        LambdaQueryWrapper<PkAgvTask> lambdaQueryWrapper = new LambdaQueryWrapper<>();
        lambdaQueryWrapper.eq(PkAgvTask::getTaskId, agvTaskDto.getTaskId());
        PkAgvTask pkAgvTask = pkAgvTaskMapper.selectOne(lambdaQueryWrapper);
        if (Objects.nonNull(agvTaskDto.getCode())) {
            LambdaQueryWrapper<PkAgvScheduling> pkAgvSchedulingLambdaQueryWrapper = new LambdaQueryWrapper<>();
            pkAgvSchedulingLambdaQueryWrapper.eq(PkAgvScheduling::getCode, agvTaskDto.getCode());
            pkAgvScheduling = pkAgvSchedulingMapper.selectOne(pkAgvSchedulingLambdaQueryWrapper);
        }

        if (Objects.isNull(pkAgvTask)) {
            //插入数据库
            saveTask(agvTaskDto, pkAgvScheduling);
        } else {
            updateTask(pkAgvTask, agvTaskDto, pkAgvScheduling);
        }
    }


    private void saveTask(AGVTaskDto agvTaskDto, PkAgvScheduling pkAgvScheduling) {

        PkAgvTask pkAgvTask = new PkAgvTask();
        pkAgvTask.setTaskId(agvTaskDto.getTaskId());
        pkAgvTask.setCode(Objects.isNull(agvTaskDto.getCode()) ? null : agvTaskDto.getCode());
        pkAgvTask.setType(agvTaskDto.getType());
        pkAgvTask.setState(agvTaskDto.getState());
        pkAgvTask.setRegion(agvTaskDto.getRegion());
        pkAgvTask.setPosition(BoxLocationNo.getByAgv(Integer.parseInt(agvTaskDto.getPosition())).getId());
        pkAgvTask.setStartTime(new Date());
        if (agvTaskDto.getState() != 3) {
            packProductionLine.setAgvComing(true);
            plcDirectiveService.saveToPlc(pkAgvTask);
        }
        if (agvTaskDto.getState() == 3) {
            pkAgvTask.setFinishTime(new Date());
            if (agvTaskDto.getType() == 1) {
                pkAgvScheduling.setFinishTime(new Date());
                pkAgvScheduling.setFinishState(2);
                pkAgvSchedulingMapper.updateById(pkAgvScheduling);
            }
        }

        pkAgvTaskMapper.insert(pkAgvTask);


    }

    private void updateTask(PkAgvTask pkAgvTask, AGVTaskDto agvTaskDto, PkAgvScheduling pkAgvScheduling) {

        if (agvTaskDto.getState() == 2) {
            pkAgvTask.setState(agvTaskDto.getState());
            pkAgvTaskMapper.updateById(pkAgvTask);
            plcDirectiveService.agvRunning(agvTaskDto);
        } else {
            if (agvTaskDto.getType() == 1 && pkAgvTask.getState() != 3) {
                //重置装箱
                iPkBoxLocationRealtionService.deleteBoxLocationRealtion2(BoxLocationNo.getByAgv(Integer.parseInt(agvTaskDto.getPosition())).getId());
            }
            pkAgvTask.setState(agvTaskDto.getState());
            if (agvTaskDto.getType() == 1) {
                pkAgvScheduling.setFinishState(1);
                pkAgvScheduling.setFinishTime(new Date());
                pkAgvSchedulingMapper.updateById(pkAgvScheduling);
            }
            pkAgvTask.setFinishTime(new Date());
            packProductionLine.setAgvComing(false);
            pkAgvTaskMapper.updateById(pkAgvTask);
            plcDirectiveService.agvComplete(agvTaskDto);
        }

    }

}
